﻿using CNKI.TPI.Web.Search.Model;
using KNet.Data.Entity;
using KNet.Data.KBaseClient;
using KNet.Foundation.DRS;
using KNet.Foundation.DRS.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace CNKI.TPI.Web.Base
{
    public class DataContextDummy : IDataContext
    {
        private string defualtDB = "SysDB";
        private IDictionary<string, KNet.Data.Entity.DataContext> ctxList = null;
        private IRetrievalService drs = null;

        public DataContextDummy()
        {
            IList<string> dbList = new List<string>();
            dbList.Add(defualtDB);
            Init(dbList);
        }

        public DataContextDummy(IList<string> dbList)
        {
            if (dbList.Count == 0)
            {
                dbList.Add(defualtDB);
                dbList.Add("mysql");
            }
            Init(dbList);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ctxName"></param>
        public void AddCtx(string ctxName)
        {
            ctxList.Add(ctxName, KNet.Data.Entity.DataContext.GetByConfigName(ctxName));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbList"></param>
        private void Init(IList<string> dbList)
        {
            ctxList = new Dictionary<string, KNet.Data.Entity.DataContext>();
            foreach (string item in dbList)
            {
                ctxList.Add(item, KNet.Data.Entity.DataContext.GetByConfigName(item));
            }
            if (ConfigHelper.IsDrsConfigExsit())
            {
                ChannelFactory<IRetrievalService> channel = new ChannelFactory<IRetrievalService>("drs_tcp");
                drs = channel.CreateChannel();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public bool Insert<T>(T model, string tableName = null, string ctxName = null) where T : new()
        {

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public bool Update<T>(T model, string tableName = null, string ctxName = null) where T : new()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public bool Delete<T>(Expression<Func<T, bool>> match, string tableName = null, string ctxName = null) where T : new()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public bool Delete<T>(T model, string tableName = null, string ctxName = null) where T : new()
        {
            return true;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <returns></returns>
        public IList<T> Get<T>(Expression<Func<T, bool>> match, Expression<Func<T, bool>> order = null, string ctxName = null, int dataCacheTimeout = 0) where T : BaseModel, IView, new()
        {
            IList<T> result = new List<T>();
            T entity = GetEntity<T>();
            if (entity != null)
            {
                result.Add(entity);
            }
            return result;
        }

        public IList<T> Get<T>(Expression<Func<T, bool>> match, int pageIndex, int pageSize, out int count, Expression<Func<T, bool>> order = null, string ctxName = null, int dataCacheTimeout = 0) where T : BaseModel, IView, new()
        {
            IList<T> result = new List<T>();
            T entity = GetEntity<T>();
            if (entity != null)
            {
                result.Add(entity);
            }
            count = 1;
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <returns></returns>
        public IList<T> GetAll<T>(Expression<Func<T, bool>> order = null, string ctxName = null, int dataCacheTimeout = 0) where T : BaseModel, IView, new()
        {
            IList<T> result = new List<T>();
            T entity = GetEntity<T>();
            if (entity != null)
            {
                result.Add(entity);
            }
            return result;
        }

        public IList<T> GetAll<T>(int pageIndex, int pageSize, out int count, Expression<Func<T, bool>> order = null, string ctxName = null, int dataCacheTimeout = 0) where T : BaseModel, IView, new()
        {
            IList<T> result = new List<T>();
            T entity = GetEntity<T>();
            if (entity != null)
            {
                result.Add(entity);
            }
            count = 1;
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public bool ExecuteNonQuery(string sql, string ctxName = null)
        {
            return true; 
        }

        public int ExecuteSqlNonQuery(string sql, string ctxName = null)
        {
            return 1;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public DataTable ExecuteSql(string sql, string ctxName = null, int maxLength = 512, int dataCacheTimeout = 0)
        {
            DataTable result = new DataTable();
            result.Columns.Add("getsysfield(__tablename)");
            return result;
        }

        public DataTable ExecuteSql(string sql, int pageIndex, int pageCount, out int count, bool isUnicode, string ctxName = null, int dataCacheTimeout = 0, string connectStr = null)
        {
            DataTable result = new DataTable();
            result.Columns.Add("getsysfield(__tablename)");
            count = 0;
            return result;
        }

        public DataSet ExecuteSql(string sql, IList<string> tableList, int pageIndex, int pageCount, bool isUnicode, string ctxName = null, int dataCacheTimeout = 0)
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        public IList<T> ExecuteSql<T>(string sql, string ctxName = null, int maxLength = -1, int dataCacheTimeout = 0) where T : BaseModel, IView, new()
        {
            IList<T> result = new List<T>();
            T entity = GetEntity<T>();
            if (entity != null)
            {
                result.Add(entity);
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <param name="fields"></param>
        /// <param name="query"></param>
        /// <param name="group"></param>
        /// <param name="order"></param>
        /// <param name="start"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public DataSet QueryByDRS(string type, string fields, string query, string group, string order, int start, int length)
        {
            DataSet ds = new DataSet();
            return ds;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drsName"></param>
        /// <param name="resource"></param>
        /// <returns></returns>
        public OperateResult AppendDbResource(string drsName, DbResource resource, decimal weight, string group)
        {
            OperateResult or = new OperateResult(0,"");
            return or;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="retrieval"></param>
        /// <returns></returns>
        public OperateResult AppendRetrieval(Retrieval retrieval)
        {
            OperateResult or = new OperateResult(0, "");
            return or;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drsName"></param>
        /// <param name="resourceName"></param>
        /// <returns></returns>
        public OperateResult RemoveResource(string drsName, string resourceName)
        {
            OperateResult or = new OperateResult(0, "");
            return or;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="drsName"></param>
        /// <returns></returns>
        public OperateResult RemoveRetrieval(string drsName)
        {
            OperateResult or = new OperateResult(0, "");
            return or;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="match"></param>
        /// <returns></returns>
        public IList<T> Gets<T>(Expression<Func<T, bool>> match,int start,int length,out int count, Expression<Func<T, bool>> order = null,
            bool loadLazy=false, string tableName = null,string ctxName = null) where T : IView, new()
        {
            IList<T> result = new List<T>();
            count = 0;
            return result;
        }

        private T GetEntity<T>() where T : new()
        {
            T result = new T();
            PropertyInfo[] propertyInfoList = result.GetType().GetProperties();
            foreach (PropertyInfo item in propertyInfoList)
            {
                MethodInfo methodInfo = item.GetSetMethod();
                if (methodInfo != null)
                {
                    if (item.PropertyType == typeof(Int32))
                    {
                        methodInfo.Invoke(result, new object[] { 1 });
                    }
                    else if (item.PropertyType == typeof(string))
                    {
                        methodInfo.Invoke(result, new object[] { "1" });
                    }
                    else if (item.PropertyType == typeof(DateTime))
                    {
                        methodInfo.Invoke(result, new object[] { DateTime.Now });
                    }
                }
            }
            if (result.GetType() == typeof(SYS_CMS_USER))
            {
                SYS_CMS_USER obj = result as SYS_CMS_USER;
                obj.Username = "sa";
                obj.Password = "";
            }
            if (result.GetType() == typeof(SYS_CMS_USER_IP))
            {
                SYS_CMS_USER_IP obj = result as SYS_CMS_USER_IP;
                obj.SIP = "0.0.0.0";
                obj.EIP = "255.255.255.255";
            }
            return result;
        }

        public int InsertRec(string tableName, string content, bool isUnicode)
        {
            return 1;
        }

        public bool UpdateRec(string sysid, string tableName, string content, bool isUnicode)
        {
            return true;
        }

        public HS_TABLE_FIELD GetFieldInfo(string tableName, string fieldName)
        {
            return new HS_TABLE_FIELD();
        }

        public byte[] GetBinary(string id)
        {
            return null;
        }

        public bool SaveFile(string srcFile, string targetFile)
        {
            return true;
        }

        public bool DeleteFile(string filePath)
        {
            return true;
        }
    }
}
